package com.example.back.service.impl;


import cn.hutool.crypto.digest.DigestUtil;
import com.example.back.constants.Login;
import com.example.back.dto.resp.LoginResp;
import com.example.back.dto.req.LoginReq;
import com.example.back.jpa.AdminRepository;
import com.example.back.jpa.BlacklistIpRepository;
import com.example.back.jpa.SysOperatingLogRepository;
import com.example.back.service.SysAdminService;
import com.example.common.entity.Admin;
import com.example.common.entity.BlacklistIp;
import com.example.common.entity.OperatingLog;
import com.example.common.support.ApiException;
import com.example.common.utils.IdUtils;
import com.example.common.utils.CheckUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.javers.spring.annotation.JaversAuditable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


/**
 * 登录实现类
 */
@Service
public class SysAdminServiceImpl implements SysAdminService {

    @Resource
    private  HttpServletRequest httpServletRequest;

    @Resource
    private BlacklistIpRepository blacklistIpRepository;

    @Resource
    private AdminRepository sysAdminRepository;

    @Resource
    private SysOperatingLogRepository sysOperatingLogRepository;

    @Resource
    private RedisTemplate redisTemplate;
    @Override
    @JaversAuditable
    public LoginResp Login(LoginReq req){

        String hostAddress = null;
        try {
            InetAddress localHost = InetAddress.getLocalHost();
            hostAddress = localHost.getHostAddress();//获取IP地址
        }catch (Exception e){
            throw new ApiException(10000,e.getMessage());
        }


        CheckUtils.checkNull(req, new ApiException(1, "对象不能为空"));
        CheckUtils.checkNull(req.getUsername(), new ApiException(1, "请输入用户名"));
        CheckUtils.checkNull(req.getPassword(), new ApiException(1, "请输入密码"));
        CheckUtils.checkNull(req.getValidate(), new ApiException(1, "请输入验证码"));
        CheckUtils.checkNull(req.getValidateId(), new ApiException(1, "验证码流水有误"));
        String validateCode=(String)redisTemplate.opsForValue().get(Login.VALIDATE_ID + req.getValidateId());
        Admin admin = sysAdminRepository.findByUsername(req.getUsername());
        String ErrCount = (String) redisTemplate.opsForValue().get(Login.LOGIN_COUNT+admin.getId());
        String lockTime = (String)redisTemplate.opsForValue().get(Login.LOCK_TIME+admin.getId());

        int strErrCount = 0;

        if(ErrCount !=null){
            strErrCount = Integer.parseInt(ErrCount);
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 格式化时间
        Date date = new Date();// 获取当前时间
        Date dateTime = null;
        Date dateDayTime = null;
        try {
            if(lockTime !=null){
                dateTime = sdf.parse(lockTime);
            }

            String dateDay = sdf.format(date);
            dateDayTime = sdf.parse(dateDay);

        }catch (Exception e){
            throw new ApiException(10001,e.getMessage());
        }


        if (!ObjectUtils.isEmpty(ErrCount) && strErrCount >=5 && dateDayTime.getTime() <= dateTime.getTime()) {
            throw new ApiException(1, "账号已锁定，将于"+ lockTime + "后解锁");
        }
        if(validateCode == null){
            throw new ApiException(1, "验证码失效，请获取新的验证码");
        }
        if (!validateCode.equals(req.getValidate())) {
            throw new ApiException(1, "验证码错误");
        }
        String password = DigestUtil.md5Hex(req.getPassword());

        BlacklistIp blacklistIp = blacklistIpRepository.findByIpAddress(hostAddress);
        if(blacklistIp !=null){
            throw new ApiException(1, "账号被限制登录");
        }

        if(admin==null){
            throw new ApiException(1, "用户不存在");
        }

        if(!admin.getPassword().equals(password)){

            int zCount = 5;
            int errCount = 1;
            String eMsg = null;
            if(!ObjectUtils.isEmpty(ErrCount)){
                errCount = strErrCount+1;
                redisTemplate.opsForValue().set(Login.LOGIN_COUNT+admin.getId(),errCount);
                eMsg = "继续尝试"+ (zCount - errCount) + "次后账号将锁定";
            }

            if(errCount >= zCount){
                Calendar cal = Calendar.getInstance();
                cal.setTime(date);
                cal.add(Calendar.MINUTE, 10);
                date = cal.getTime();
                redisTemplate.opsForValue().set(Login.LOCK_TIME+admin.getId(),sdf.format(date));
                eMsg = "账号已锁定，10分钟后解锁";
            }

            throw new ApiException(1, "用户密码错误");
        }else{
            redisTemplate.delete(Login.LOGIN_COUNT+admin.getId());
            redisTemplate.delete(Login.LOCK_TIME+admin.getId());
            redisTemplate.delete(Login.VALIDATE_ID + req.getValidateId());
        }

        if(admin.getDisable()==true){
            throw new ApiException(1, "该帐户已被禁用");
        }

        OperatingLog operatingLog = new OperatingLog();
        operatingLog.setId(IdUtils.generateId());
        operatingLog.setUid(admin.getId());
        operatingLog.setCreateTime(new Date());
        operatingLog.setOType(1);
        operatingLog.setOperatingTxt("登陆IP："+ hostAddress);
        sysOperatingLogRepository.save(operatingLog);

        //赋值
        LoginResp resp = new LoginResp();
        resp.setUID(admin.getId());
        resp.setAccount(admin.getUsername());
        resp.setName(admin.getName());
        resp.setDepartName(admin.getDepartName());
        resp.setNeedChangePWD(admin.getEditTime().before(new Date()));
        return resp;
    }
}
